<?php
/* explain:
 * 
 * @ link 		http://www.marsemd.com/
 * @ Email		ldmmyx@hotmail.com
 * @ copyright 	2005  ivan Ling Deming	
 * @ author 	gaby  ivan Ling Deming
 * @ version 2.0
 *
 */
include_once("utils/DBUtils.php");
class SessionImpl extends DBUtils 
{
	private $conn;
	
	private $session   				= array();
	private $arrDomain 				= array();	
	
	private $sessionId				= '';
	private $cookieName;
	private $cookiePath				= '/';
	private $cookieDomain			= '';
	private $expires				= 1800; //--> expire unit: second
	
	private $session_existed 		= false;	
	private $session_data_max_len 	= 500;
	
	private $userId;
	private $startTime;
	private $lastActiveTime;
	
	private $session_table_name;
	
	public function __construct($DBTag = 'system', $cookieName = 'SESSION_ID', $sessionTableName = 'sessionheap')
	{
		$this->DBTag 				= $DBTag;
		$this->cookieName			= $cookieName;		
		$this->session_table_name	= $sessionTableName;
		
		parent::__construct();
		$this->conn = $this->getConnection($DBTag);
		
		if($this->conn){
			$sql = "CREATE TABLE IF NOT EXISTS " . $this->session_table_name . " (
				    session_id 			CHAR(32) NOT NULL,
				   	userid				int(11) unsigned NOT NULL default '0',
				    start_time 			timestamp NOT NULL,
				    last_active_time 	timestamp NOT NULL,
				    session_data 		varchar(500) DEFAULT NULL,
				    PRIMARY KEY 		(session_id),
				    UNIQUE sessionid_time (session_id, last_active_time)) TYPE=HEAP";
    		$rs  = mysql_query($sql,$this->conn);  
		}
		
		$this->init();
	}
	
	/* Session
	 * 
	 * @param  array  	arrDomain  
	 * @param  int 			expires
	 */
	public function init($arrDomain = ARR_DOMAIN, $expires = INT_EXPIRES)
	{
		if(!empty($expires))
			$this->expires = $expires;//--> timeout

		if(!empty($arrDomain)){
			$arrtmp = explode(",",$arrDomain);
			if(in_array("127.0.0.1", $arrtmp) || in_array("localhost", $arrtmp)){
				foreach ($arrtmp as $value){
					if($value != '127.0.0.1' && $value != 'localhost')
						$this->arrDomain[] = $value;
				}
			}else
				$this->arrDomain = $arrtmp;
		}
	}

	/* session
	 * 
	 * @param  return int 1: true  0: false
	 */
	public function isExisted()
	{  
		if(!is_resource($this->conn)) 
			return 0;
		
		global $_COOKIE;
		
		$this->sessionId = isset($_COOKIE[$this->cookieName]) ? $_COOKIE[$this->cookieName] : ''; 
		
		if($this->sessionId == ''){
			$this->session_existed = false;
			return 0;
		}else{
			$datenow = date('Y-m-d H:i:s');
			
			$sql 	= "SELECT * FROM sessionheap WHERE session_id='" . $this->sessionId . "' AND last_active_time> date_sub('$datenow', INTERVAL ".$this->expires." SECOND)";
			$rs 	= mysql_query($sql, $this->conn);// or die (mysql_error($this->conn)); 
			if(mysql_num_rows($rs) == 0){	
				$this->session_existed 	= false;
			}else{
				$arrBack 				= mysql_fetch_array($rs);
				$this->session 			= unserialize($arrBack['session_data']);
				
				$this->userId	  		= $arrBack['userid'];
				$this->startTime	   	= $arrBack['start_time'];
				$this->lastActiveTime 	= $arrBack['last_active_time'];
				
				$domainCount = count($this->arrDomain);
				if($domainCount > 0){
					if(strlen($this->cookieName) > 0)
						setcookie($this->cookieName,$this->sessionId, time() + $this->expires ,$this->cookiePath,$this->cookieDomain); 
					for($i=0; $i < $domainCount; $i++)
						setcookie($this->cookieName,$this->sessionId, time() + $this->expires ,$this->cookiePath,$this->arrDomain[$i]); 
				}else if(strlen($this->cookieDomain) > 0)
					setcookie($this->cookieName,$this->sessionId, time() + $this->expires, $this->cookiePath,$this->cookieDomain); 
						
								
				$this->session_existed = true;
				
				register_shutdown_function(array(&$this, "kill_timeout"), $this->DBTag, $this->expires);				
				register_shutdown_function(array(&$this, "refreshActiveTime"), $this->DBTag, $this->sessionId, $this->session, $this->session_data_max_len);			
				
				return 1;
			} 
		}
	} 
		
	/*
	 * 
	 * @param  int 	  userid  	
	 * @param  string session_data
	 * @param  return array 
	 */
	public function start($userid = 0, $session_data = array())
	{  
		if(!is_resource($this->conn)) 
			return 0;
		
		$strSessionData = addslashes(serialize($session_data));
		if(strlen($strSessionData) > $this->session_data_max_len) 
			return 0;
		
		$this->sessionId	= md5(uniqid(rand()));
		$domainCount		= count($this->arrDomain);
		if($domainCount > 0){
			if(strlen($this->cookieName) > 0)
				setcookie($this->cookieName,$this->sessionId, time() + $this->expires ,$this->cookiePath,$this->cookieDomain); 
			for($i=0; $i < $domainCount; $i++)
				setcookie($this->cookieName,$this->sessionId, time() + $this->expires ,$this->cookiePath,$this->arrDomain[$i]); 
		}else if(strlen($this->cookieDomain) > 0)
			setcookie($this->cookieName,$this->sessionId, time() + $this->expires, $this->cookiePath,$this->cookieDomain); 

		$datenow = date('Y-m-d H:i:s');
		
		$sql = "INSERT INTO sessionheap SET userid = $userid, session_id = '".$this->sessionId."', start_time = '$datenow', last_active_time = '$datenow', session_data = '$strSessionData'";
		$rs  = mysql_query($sql,$this->conn);// or die('error: ' .mysql_error());  
		
		if($rs){															
			$this->session			= $session_data;
			
			$this->userId			= $userid;
			$this->startTime		= $datenow;	
			$this->lastActiveTime	= $datenow; 							
			$this->session_existed	= true;
			
			return 1;
		}else{
			$this->session_existed=false;
			
			return 0;
		}
	}
	
	public function getUserId()
	{
		return $this->userId;
	}
	
	public function getGroupId()
	{
		return $this->session['gid'];
	}
	
	public function getUserName()
	{
		return $this->session['uname'];
	}
	
	public function getStartTime()
	{
		return $this->startTime;
	}
	
	public function getLastActiveTime()
	{
		return $this->lastActiveTime;
	}
	
	public function getData()
	{
		return $this->session;
	}
	
	public function getSessionId()
	{
		return $this->sessionId;
	}
	
	public function getLanguage()
	{
		return $this->session['lan'];
	}
	
	public function getLoginId()
	{
		return $this->session['login_id'];
	}
	
	/*
	 *
	 *
	 * @param  return int
	 */
	public function refreshActiveTime($DBTag, $sessionId, $arrSession, $session_data_max_len)
	{ 
		$strSessionData = addslashes(serialize($arrSession));
		if(strlen($strSessionData) < $session_data_max_len){
			$datenow = date('Y-m-d H:i:s');
			
			$sql = "UPDATE sessionheap SET session_data = '$strSessionData', last_active_time = '$datenow' where session_id = '$sessionId'";

			$conn 		= null;
			
			try{
				$conn 	= $this->getConnection($DBTag);//
				$rs  	= mysql_query($sql, $conn);
			}catch(Exception $e){			
				echo mysql_error($conn) . $sql;
			}
			
			$this->freeConnection($DBTag, $conn);
		}		
	}
	
	/*
	 *
	 * @param  array session_data
	 * @param  return int
	 */
	public function add($session_data = array())
	{ 
		if(!is_resource($this->conn)) 
			return 0;

		if($this->session_existed){
			$arrSessionTmp   = $this->session;
			$arrSessionTmp  = array_merge($arrSessionTmp,$session_data);
			$strSessionData = addslashes(serialize($arrSessionTmp));
			
			
			if(strlen($strSessionData) > $this->session_data_max_len)
				return 0;
			else{
				$datenow = date('Y-m-d H:i:s');
				
				$sql = "UPDATE sessionheap SET session_data='$strSessionData', last_active_time='$datenow' WHERE session_id = '".$this->sessionId."'";
				$rs  = mysql_query($sql,$this->conn);
				if($rs){
					$this->lastActiveTime	= $datenow; 	
					$this->session 			= $arrSessionTmp;
					
					return 1;
				}else
					return 0;
			}
		}else
			return 0;
	} 
	
	/* session_destroy()
	 * 
	 * @param  return int
	 */
	public function destroy()
	{ 
		$isreturn 	= false;
		$conn 		= null;
		
		$sql = "DELETE FROM sessionheap WHERE session_id = '".$this->sessionId."'";
		
		try{
			$conn 	= $this->getConnection($this->DBTag);
			$rs  	= mysql_query($sql, $conn);

			if($rs && mysql_affected_rows($conn) > 0){
				$isreturn = true;
			}
		}catch(Exception $e){
			$this->message = $e->getMessage();
			
			echo mysql_error($conn) . $sql;
		}
		
		$this->freeConnection($this->DBTag, $conn);
			
		return $isreturn;
	}
	/* 
	 *
	 * @param  return int
	 */
	public function kill_timeout($DBTag, $expires)
	{ 
		$datenow 	= date('Y-m-d H:i:s');
		$sql  		= "DELETE FROM sessionheap WHERE last_active_time < DATE_SUB('$datenow', interval $expires SECOND)";

		$conn 		= null;
		
		try{
			$conn 	= $this->getConnection($DBTag);
			$rs  	= mysql_query($sql, $conn);
		}catch(Exception $e){			
			echo mysql_error($conn) . $sql;
		}
		
		$this->freeConnection($DBTag, $conn);			
	} 
}
?>
